package org.hilo.boot.core.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.AdviceFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

/**
 * Execute subject.logout() then response json data {"success":true}
 * @deprecated use Controller instead
 * 
 * @author zollty
 * @since 2018-09-02
 */
public class AjaxLogoutFilter extends AdviceFilter {
    private static final Logger log = LoggerFactory.getLogger(AjaxLogoutFilter.class);
    public final static String APPLICATION_JSON = "application/json";

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = getSubject(request, response);
        // try/catch added for SHIRO-298:
        try {
            subject.logout();
        } catch (SessionException ise) {
            log.debug("Encountered session exception during logout.  This can generally safely be ignored.", ise);
        }
        render(WebUtils.toHttp(response), "{\"success\":true}");
        return false;
    }
    
    protected static void render(HttpServletResponse response, String message) throws IOException {
        response.setContentType(APPLICATION_JSON);
        response.setCharacterEncoding("utf-8");
        PrintWriter writer = response.getWriter();
        writer.println(message);
        writer.flush();
    }

    /**
     * Returns the currently executing {@link Subject}. This implementation merely defaults to calling
     * {@code SecurityUtils.}{@link org.apache.shiro.SecurityUtils#getSubject() getSubject()}, but can be overridden by
     * subclasses for different retrieval strategies.
     *
     * @param request
     *            the incoming Servlet request
     * @param response
     *            the outgoing Servlet response
     * @return the currently executing {@link Subject}.
     */
    protected Subject getSubject(ServletRequest request, ServletResponse response) {
        return SecurityUtils.getSubject();
    }
    
}
